package config

import (
	"fmt"
	"os"

	"github.com/spf13/viper"
)

type Config struct {
	Server     ServerConfig     `mapstructure:"server"`
	Database   DatabaseConfig   `mapstructure:"database"`
	Redis      RedisConfig      `mapstructure:"redis"`
	JWT        JWTConfig        `mapstructure:"jwt"`
	AIService  AIServiceConfig  `mapstructure:"ai_service"`
	Upload     UploadConfig     `mapstructure:"upload"`
	Log        LogConfig        `mapstructure:"log"`
	CORS       CORSConfig       `mapstructure:"cors"`
	WebSocket  WebSocketConfig  `mapstructure:"websocket"`
	Livestream LivestreamConfig `mapstructure:"livestream"`
}

type ServerConfig struct {
	Port       string `mapstructure:"port"`
	RTMPPort   string `mapstructure:"rtmp_port"`
	WebRTCPort string `mapstructure:"webrtc_port"`
}

type DatabaseConfig struct {
	Host           string `mapstructure:"host"`
	Port           string `mapstructure:"port"`
	User           string `mapstructure:"user"`
	Password       string `mapstructure:"password"`
	DBName         string `mapstructure:"dbname"`
	SSLMode        string `mapstructure:"sslmode"`
	MaxConnections int    `mapstructure:"max_connections"`
}

type RedisConfig struct {
	Host     string `mapstructure:"host"`
	Port     string `mapstructure:"port"`
	Password string `mapstructure:"password"`
	DB       int    `mapstructure:"db"`
}

type JWTConfig struct {
	Secret   string `mapstructure:"secret"`
	ExpiresIn int    `mapstructure:"expires_in"`
}

type AIServiceConfig struct {
	URL     string `mapstructure:"url"`
	Timeout int    `mapstructure:"timeout"`
}

type UploadConfig struct {
	MaxSize    string   `mapstructure:"max_size"`
	AllowedTypes []string `mapstructure:"allowed_types"`
	Path       string   `mapstructure:"path"`
}

type LogConfig struct {
	Level  string `mapstructure:"level"`
	Format string `mapstructure:"format"`
	Output string `mapstructure:"output"`
}

type CORSConfig struct {
	AllowedOrigins []string `mapstructure:"allowed_origins"`
	AllowedMethods []string `mapstructure:"allowed_methods"`
	AllowedHeaders []string `mapstructure:"allowed_headers"`
}

type WebSocketConfig struct {
	MaxConnections int `mapstructure:"max_connections"`
	ReadTimeout    int `mapstructure:"read_timeout"`
	WriteTimeout   int `mapstructure:"write_timeout"`
}

type LivestreamConfig struct {
	MaxDuration     int    `mapstructure:"max_duration"`
	MaxViewers      int    `mapstructure:"max_viewers"`
	EnableRecording bool   `mapstructure:"enable_recording"`
	RecordingPath   string `mapstructure:"recording_path"`
}

func LoadConfig() (*Config, error) {
	viper.SetConfigName("config")
	viper.SetConfigType("yaml")
	viper.AddConfigPath(".")
	viper.AddConfigPath("./config")
	viper.AddConfigPath("/etc/miracle-recorder")

	// 设置环境变量默认值
	viper.SetDefault("server.port", "8080")
	viper.SetDefault("server.rtmp_port", "1935")
	viper.SetDefault("server.webrtc_port", "8443")
	viper.SetDefault("database.max_connections", 25)
	viper.SetDefault("jwt.expires_in", 3600)
	viper.SetDefault("ai_service.timeout", 30)
	viper.SetDefault("websocket.max_connections", 1000)
	viper.SetDefault("livestream.max_duration", 3600)
	viper.SetDefault("livestream.max_viewers", 1000)

	// 从环境变量读取
	viper.AutomaticEnv()

	// 读取配置文件
	if err := viper.ReadInConfig(); err != nil {
		if _, ok := err.(viper.ConfigFileNotFoundError); ok {
			// 配置文件未找到，使用默认值
			fmt.Println("Config file not found, using defaults and environment variables")
		} else {
			return nil, fmt.Errorf("error reading config file: %w", err)
		}
	}

	var config Config
	if err := viper.Unmarshal(&config); err != nil {
		return nil, fmt.Errorf("unable to decode config: %w", err)
	}

	// 从环境变量覆盖敏感配置
	if dbHost := os.Getenv("DB_HOST"); dbHost != "" {
		config.Database.Host = dbHost
	}
	if dbPort := os.Getenv("DB_PORT"); dbPort != "" {
		config.Database.Port = dbPort
	}
	if dbUser := os.Getenv("DB_USER"); dbUser != "" {
		config.Database.User = dbUser
	}
	if dbPassword := os.Getenv("DB_PASSWORD"); dbPassword != "" {
		config.Database.Password = dbPassword
	}
	if dbName := os.Getenv("DB_NAME"); dbName != "" {
		config.Database.DBName = dbName
	}
	if redisHost := os.Getenv("REDIS_HOST"); redisHost != "" {
		config.Redis.Host = redisHost
	}
	if redisPort := os.Getenv("REDIS_PORT"); redisPort != "" {
		config.Redis.Port = redisPort
	}
	if jwtSecret := os.Getenv("JWT_SECRET"); jwtSecret != "" {
		config.JWT.Secret = jwtSecret
	}
	if aiServiceURL := os.Getenv("AI_SERVICE_URL"); aiServiceURL != "" {
		config.AIService.URL = aiServiceURL
	}

	return &config, nil
}